package ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager;

import com.querydsl.core.types.Predicate;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

/**
 * 基础数据实体业务逻辑.
 *
 * @author caspar
 */
public interface Manager<EntityT, IdT> {

  /**
   * 获取新的id
   * @return 新的id
   */
  IdT getNewId();

  /**
   * 保存实体，新增或修改.保存全部字段（包含null字段)
   *
   * @param entity 数据实体
   * @return 实体id
   */
  IdT save(EntityT entity);

  /**
   * 保存实体，新增或修改
   *
   * @param entity            实体
   * @param saveNullFieldFlag 是否保存null字段
   * @return 实体id
   */
  IdT save(EntityT entity, boolean saveNullFieldFlag);

  /**
   * 保存实体，新增或修改,但忽略框架注解字段.
   *
   * {@link org.springframework.data.annotation.Version}
   * {@link org.springframework.data.annotation.LastModifiedDate}
   * {@link org.springframework.data.annotation.CreatedDate}
   * {@link ace.cmp.spring.data.jdbc.querydsl.core.annotations.LogicDelete}
   * {@link ace.cmp.spring.data.jdbc.querydsl.core.annotations.Ignore}
   *
   * @param entity            实体
   * @param saveNullFieldFlag 是否保存null字段
   * @return 实体id
   */
  IdT saveIgnore(EntityT entity, boolean saveNullFieldFlag);

  /**
   * 新增或修改数据,根据id字段是否有值决定新增或修改.
   *
   * @param entity 实体
   * @param saveNullFieldFlag 是否保存null字段
   * @return 实体id
   */
  IdT saveEntityByConditionHasId(EntityT entity, boolean saveNullFieldFlag);

  /**
   * 新增
   *
   * @param entity 实体
   * @return 实体id
   */
  IdT add(EntityT entity);

  /**
   * 新增
   *
   * @param entity            实体
   * @param saveNullFieldFlag 是否保存null字段
   * @return 实体id
   */
  IdT add(EntityT entity, Boolean saveNullFieldFlag);

  /**
   * 新增数据.
   * 但忽略框架注解相关字段,由框架自动处理
   *
   * @param entity            实体
   * @param saveNullFieldFlag 是否保存null字段
   * @return 实体id
   */
  IdT addIgnore(EntityT entity, boolean saveNullFieldFlag);

  /**
   * 新增数据.
   * 但忽略框架注解相关字段,由框架自动处理
   *
   * @param entities            实体
   * @param saveNullFieldFlag 是否保存null字段
   * @return 实体id
   */
  long addIgnore(Collection<EntityT> entities, boolean saveNullFieldFlag);

  /**
   * 修改
   *
   * @param entity 实体
   * @return 实体id
   */
  IdT modify(EntityT entity);

  /**
   * 修改.
   *
   * @param entity            实体
   * @param saveNullFieldFlag 是否保存null字段
   * @return 实体id
   */
  IdT modify(EntityT entity, boolean saveNullFieldFlag);

  /**
   * 修改数据.
   * 但忽略框架注解相关字段,由框架自动处理
   *
   * @param entity            实体
   * @param saveNullFieldFlag 是否保存null字段
   * @return 实体id
   */
  IdT modifyIgnore(EntityT entity, boolean saveNullFieldFlag);

  /**
   * 修改数据.
   * 但忽略框架注解相关字段,由框架自动处理
   *
   * @param entities            实体
   * @param saveNullFieldFlag 是否保存null字段
   * @return 实体id
   */
  long modifyIgnore(Collection<EntityT> entities, boolean saveNullFieldFlag);

  boolean remove(IdT id);

  boolean remove(List<IdT> ids);

  boolean remove(Predicate predicate);

  boolean removeLogic(IdT ids);

  boolean removeLogic(List<IdT> ids);

  boolean removeLogic(Predicate predicate);

  EntityT getById(IdT id);

  EntityT getOne(Predicate predicate);

  List<EntityT> getListByIdIn(List<IdT> ids);

  List<EntityT> getList(Predicate predicate);

  Map<IdT, EntityT> getMapByIdIn(List<IdT> ids);

  Map<IdT, EntityT> getMap(Predicate predicate);

  Page<EntityT> search(String query, Pageable pageable);

  Page<EntityT> search(Predicate predicate, Pageable pageable);

  /**
   * 解析rsql查询语句.
   * @param rsql rsql查询语句
   * @return spring data jdbc querydsl 查询语句
   */
  Predicate parseRsql(String rsql);

  /**
   * 是否新实体，判断方法：根据id字段是否存,并查询id字段实体数据是否存在.
   * @param entity 实体
   * @return true / false
   */
  boolean isNew(EntityT entity);

  boolean hasEntityId(EntityT entity);

  boolean hasNonEntityId(EntityT entity);

  boolean existById(EntityT entity);

  boolean existNonById(EntityT entity);

  IdT getEntityId(EntityT entity);

}
